package net.java.mediasearch.service;

import java.io.IOException;
import java.io.InputStream;

import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import net.java.mediasearch.exception.MediaSearchException;
import net.java.mediasearch.model.MediaEntity;
import net.java.mediasearch.model.SmallMediaEntity;

/**
 * MediaSearchService OFDB Implementation.
 * Implementation using the Webservice of the OFDBGW (Online Film Datenbank GateWay) to search for Media.
 */
public class MediaSearchServiceOfdbImpl implements MediaSearchService {

	private static String BASE_URL = "http://ofdbgw.org/";
	
	private HttpClient httpClient;
	
	ResponseXMLParser responseXmlParser = new ResponseXMLParser();
	
	/**
	 * Initialization Method.
	 * Has to be called before using this Service-Class.
	 */
	public void init() {
		HttpParams httpParams = new BasicHttpParams();
		httpParams.setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
		httpParams.setParameter("http.protocol.content-charset", "UTF-8");
		HttpConnectionParams.setConnectionTimeout(httpParams, 2000);
		HttpConnectionParams.setSoTimeout(httpParams, 3000);
		
		this.httpClient = new DefaultHttpClient(httpParams);
	}
	
	/**
	 * Destroy-Method.
	 * Has to be called when this Service-Class is no longer used.
	 */
	public void shutDown() {
		this.httpClient.getConnectionManager().shutdown();
	}
	
	public List<SmallMediaEntity> getSmallMediaEntitiesByMediaTitle(String mediaTitle) throws MediaSearchException {
		String requestPath = new StringBuilder(BASE_URL).append("search/").append(mediaTitle).toString();
		
		InputStream inputStream = executeRequest(requestPath);
		
		return responseXmlParser.parseXmlResponseContaintingMediaEntityList(inputStream);
	}
	
	private InputStream executeRequest(String requestPath) throws MediaSearchException {
		HttpGet getRequest = new HttpGet(requestPath);
		
		try {
			HttpResponse response = this.httpClient.execute(getRequest);
			
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				throw new MediaSearchException(String.format("Http Statuscode %d [%s] got the sent request!", 
						response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
			}
			
			HttpEntity httpEntity = response.getEntity();
			return httpEntity.getContent();
			
		} catch(ClientProtocolException clientProtocolException) {
			throw new MediaSearchException("Exception occured searching for Media!", clientProtocolException);
		} catch(IOException ioException) {
			throw new MediaSearchException("Exception occured searching for Media!", ioException);
		}
	}

	public MediaEntity getMediaEntityByMediaId(String mediaId) throws MediaSearchException {
		String requestPath = new StringBuilder(BASE_URL).append("movie/").append("" + mediaId).toString();
		
		InputStream inputStream = executeRequest(requestPath);
		
		MediaEntity mediaEntity = responseXmlParser.parseXmlResponseContaintingMediaEntiyDetail(inputStream);
		mediaEntity.setId(mediaId);
		return mediaEntity;
	}
}
